home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dirut
/
bm_rm.zip
/
RM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-17
|
21KB
|
473 lines
/* RM - Remove files and/or directory subtrees
Copyright (C) 1989, 1990, 1991 Brian B. McGuinness
15 Kevin Road
Scotch Plains, NJ 07076
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 1, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.
This is an extended MS-DOS implementation of the *NIX RM utility.
Syntax: RM [/AEFIRSV?] {name | @}...
/A = Detect all files, even hidden and system files, which are not normally
detected. If RM is used to remove files in the root directory of a
bootable disk, especially a hard disk, /A should not be used with /F
as there is a risk of removing the system files IBMBIO.COM (IO.SYS) and
IBMDOS.COM (MSDOS.SYS). This would make it impossible to boot the system
from that disk.
/E = Only delete matching files whose file size is zero. Normally, we delete
matching files regardless of their size. This option is useful for
disposing of empty "junk" files produced by programs or by failed
attempts at I/O redirection. For example, to remove ALL empty files from
drive C:, use the command RM /ES C:\*.* (/S is explained below). Note
that empty files use up no disk space but they do use up a directory entry.
/F = Force deletion of files without asking. Normally, we prompt the user for
confirmation before removing read-only, hidden, or system files or before
assuming "\*.*" at the end of a directory name (see /R below). If the /F
switch is used, these files are removed without any prompt being given.
/I = Interactive mode: the user is prompted for confirmation before each file
is removed, regardless of the file's attributes.
/R = Recursively delete entire subtrees. Normally, when a directory name
appears on the command line it is treated as if "\*.*" was appended to
it. If the /R switch is used, RM will recursively descend through any
directory whose name is given and will remove the entire subtree that
begins with that directory.
/S = Delete matching files in entire subtree. For example, entering
RM \UTIL\*.BAK will delete all files in the \UTIL directory which have
the extension .BAK. Typing RM /S \UTIL\*.BAK will delete all .BAK
files in the \UTIL directory and all subdirectories of \UTIL. Typing
RM /S *.DOC will remove all .DOC files in the current default directory
and all of its subdirectories. /S ignores directory names: e.g., if you
have a directory called \ASM, then typing RM /S \ASM will do nothing. To
remove all files in \ASM and its subdirectories, type RM /S \ASM\*.*.
This will only remove files, not directories. Use /R to remove a whole
subtree.
/V = Verbose: display the name of each file or directory as it is removed.
/? = Display instructions for using this program
Note: Switches become active as they are encountered on the command line. If
a switch is to affect a given file, it must appear before the file's
name on the command line.
name = name of a file or directory to be removed. Wildcards may be used.
@ = Read a list of names and/or switches from the standard input device and
treat each of these as if it had been typed on the command line as an
argument of RM. More than one name and/or switch may appear on each
line of input. When an EOF is encountered, processing of the command
line resumes.
This feature is useful when used with a file containing a lengthy list
of names of files to be deleted. It may also be used with any program
which writes a list of file names to standard output: e.g. a program
which lists all files in a given directory which have not been modified
since a certain date.
If the environment string VERBOSE exists and has the value ON, then RM will
act as though the /V switch is in effect even if /V is not included on the
command line.
1.00 August 1989 - Original version.
1.01 August 1989 - If the user presses a special key (e.g. F10) after being
prompted for a yes or no answer, don't echo a weird char.
Also speed up character string output.
1.02 September 1989 - Allow the use of Esc to exit from the program.
1.03 May 1990 - Minor bug fixes and code cleanup.
1.10 July 1991 - /E switch added, messages improved.
Version 1.10 C language
----------------------------------------------------------------------------- */
#include <stdio.h>
#include <direct.h> /* for remove() */
#include <io.h> /* for chmod() */
/* IF THE FOLLOWING KEYSTROKE IS READ IN RESPONSE TO A YES/NO PROMPT, THIS
PROGRAM WILL IMMEDIATELY TERMINATE EXECUTION */
#define ESCAPE 27
/* DEFINE ERROR CODES */
#define SUCCESS 0
#define BADSYNTAX 11
#define BADSWITCH 13
/* DEFINE FILE ATTRIBUTES */
#define NORMAL 0
#define READONLY 1
#define HIDDEN 2
#define SYSTEM 4
#define DIRECTORY 16
#define ARCHIVE 32
/* DEFINE FLAG VALUES FOR COMMAND LINE SWITCHES */
#define EMPTY 1 /* /E */
#define FORCED 2 /* /F */
#define INTERACTIVE 4 /* /I */
#define RECURSIVE 8 /* /R */
#define GLOBAL 16 /* /S */
#define VERBOSE 32 /* /V */
/* DEFINE DATA STRUCTURE RETURNED FROM findfile() */
/* Note: In the time, S = seconds / 2; in the date, Y = year - 1980 */
struct DIRINFO {
char reserved[21]; /* Undocumented (varies with DOS version) */
unsigned char attrib; /* Attribute byte: 00ADVSHR */
unsigned short time; /* Time file was saved: HHHHHMMMMMMSSSSS */
unsigned short date; /* Date file was saved: YYYYYYYMMMMDDDDD */
unsigned long size; /* File size in bytes */
char name[13]; /* File name */
};
/*----------------------------------------------------------------------------*/
main (int argc, char **argv) {
void delete (char *pathname, struct DIRINFO *file, int flags); /* Remove a file */
int delglobal (char *fname, int attributes, int flags, char *end); /* Delete file in all subdirectories */
int delmatch (char *fname, int attributes, int flags, char *end); /* Delete matching files */
int fexpand (char *relname, char *absname); /* Fully qualify file name */
int findfile (char *fname, int srchattr, struct DIRINFO *); /* Search directory for a file */
int getkeyn(); /* Read keystroke and print newline */
short getmode (char *fname); /* Get file attributes */
char *nexttok (int *argc, char ***argv, int *inpflag); /* Get next argument */
void recurse (char *path, int attributes, int flags); /* Remove a subtree */
void usage (char switchar); /* Display instructions */
char switchar; /* Current MS-DOS switch character */
int attrib; /* Attributes to use to search for matching files */
int flags; /* Keeps track of command line switches */
int filecnt; /* Keeps track of how many names we've found on cmd line */
int inpflag; /* 0 = get tokens from cmd line, otherwise get them from stdin */
char *token; /* Command line token */
int i;
char fullname[84]; /* Buffer for fully qualified file/directory name */
char *end; /* Location of end of f